#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from common.const import ReportDBLabel, BackupTypeEnum
from common.env_common import get_install_head_path


class Db2Const:
    """
    DB2常量类
    """
    # DPF集群类型
    DPF_CLUSTER_TYPE = "dpf"
    # 单机
    SINGLE = 'single'
    # HA集群
    POWERHA = "powerHA"
    # RHEL HA集群
    RHELHA = "rhelHA"
    # HADR集群
    HADR = "hadr"
    # 表空间状态Normal（十六进制状态值）
    NORMAL_STATE = "0x0000"
    # 交互函数的超时判断
    TIMEOUT = 60
    # 交互函数的读文件字节数
    MAXREAD = 8000
    # 数据库规格限制
    MAX_DATABASE_NUM = 500
    LOG_TARGET = "logtarget"
    NEW_LOGPATH = "newlogpath"
    MOUNT_PATH = "/mnt/databackup/"
    ORIGINAL = "original"
    LOCAL_DATABASE_DIRECTORY = "localDatabaseDirectory"
    REDIRECT = "redirect"
    INCREMENTAL = "incremental"
    # 存放HADR主节点前滚后非活动日志的临时目录
    TMP_PRI_LOG_DIR = "tmp_primary_log"
    # 日志备份依赖日志副本时日志完整性标记
    LOG_INTEGRITY_DEPEND_LOG_TAG = "LogIntegrityDependLog"
    # 日志备份依赖数据副本时日志完整性标记
    LOG_INTEGRITY_DEPEND_DATA_TAG = "LogIntegrityDependData"
    # 保存日志备份依赖副本信息文件的标记
    LOG_BAK_DEPEND_COPY_FILE_TAG = "LogBakDependentCopyInfo"
    # HADR主节点是否已前滚的标记
    HADR_PRI_ROLLFORWARD_TAG = "HadrPriRfw"
    CACHE_MOUNT_PATH = f"{get_install_head_path()}/DataBackup/cache"
    # 路径黑名单
    PATH_BLACK_LIST = r"^/$|^/bin$|^/bin/.*|^/boot$|^/boot/.*|^/dev$|^/dev/.*|^/etc$|^/etc/.*|" \
                      r"^/lib$|^/lib/.*|^/lib64$|^/lib64/.*|^/lost+found$|^/lost+found/.*|^/media$|^/media/.*|" \
                      r"^/mnt$|^/proc$|^/proc/.*|^/root$|^/run$|" \
                      r"^/sbin$|^/sbin/.*|^/selinux$|^/selinux/.*|^/srv$|^/srv/.*|^/sys$|^/sys/.*|" \
                      r"^/usr$|^/usr/bin$|^/usr/include$|^/usr/lib$|^/usr/local$|" \
                      r"^/usr/local/bin$|^/usr/local/include$|^/usr/local/sbin$|^/usr/local/share$|" \
                      r"^/usr/sbin$|^/usr/share$|^/usr/src$|^/var$"
    # 任务标签轮训睡眠时间
    LABEL_SLEEP_TIME = 40
    # 日志归档最小超时时间（5min）
    LOG_ARCHIVE_MIN_TIMEOUT = 300
    # 日志备份延迟时间
    LOG_SLEEP_TIME = 20
    # 备节点检查主节点前滚状态超时
    HADR_CHK_PRI_RFW_TIMEOUT = 86400
    # 副本是否损坏
    IS_DAMAGED = "isDamaged"


class Db2Regex:
    # DB2日志文件名正则
    LOG_NAME_REG = r"^S[\d]{7}\.LOG$"
    # DB2日志文件名提取数字正则
    EXTRACT_LOG_NUM_REG = r"^S([\d]{7})\.LOG$"
    # HADR主节点前滚标记结束正则
    PRI_RFW_FLAG_END_TAG = r"(True|False)$"
    # 归档日志记录信息起始正则表达式
    ARCH_LOG_INFO_BEGIN_REG = r"\s*X\s+D\s+[\d]{14,}\s+[1|2]\s+D\s+"
    # uuid4正则表达式
    UUID4_REG = r"[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}"
    # Linux路径结束正则
    LINUX_PATH_END_REG = "/{0,1}$"
    # 截取副本挂载路径正则表达式
    CUT_COPY_MOUNT_PATH_REG = r"(.*)/[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}/{0,1}$"
    # 分割“副本ID.meta”内容的正则表达式，样例：“6d2d0cf6-6f17-459d-9603-4b4b87201ab3;1680332516~1680332890;”
    COPY_META_INFO_SPLIT_RET = r";|~"


class Db2JobName:
    """
    DB2任务名称类
    """
    # 是否允许执行该任务
    ALLOW_BACKUP_IN_LOCAL = "AllowBackupInLocalNode"
    # 是否增量转全量
    CHECK_BACKUP_JOB_TYPE = "CheckBackupJobType"
    # 前置任务
    BACKUP_PRE = "BackupPrerequisite"
    # 备份任务
    BACKUP = "Backup"
    # 扫描代码仓丢脸
    QUERY_SCAN_REPOSITORIES = "QueryScanRepositories"
    # 后置任务
    BACKUP_POST = "BackupPostJob"
    # 查询副本
    QUERY_COPY = "QueryBackupCopy"
    # 查询副本
    CHECK_AND_QUERY_COPY = "check_and_queryCopy"
    # 删除副本
    DELETE_COPY = "DeleteCopy"
    # 权限检查
    QUERY_PERMISSION = "QueryJobPermission"
    ABORT_JOB = "AbortJob"
    BACKUP_PER_PROGRESS = f"{BACKUP_PRE}Progress"
    BACKUP_PROGRESS = f"{BACKUP}Progress"
    BACKUP_POST_PROGRESS = f"{BACKUP_POST}Progress"
    ABORT_JOB_PROGRESS = f"{ABORT_JOB}Progress"
    DELETE_COPY_PROGRESS = f"{DELETE_COPY}Progress"
    PAUSE_JOB = "PauseJob"
    LIVE_MOUNT = "LiveMount"
    CANCEL_LIVE_MOUNT = "CancelLiveMount"
    # 是否允许执行恢复任务
    ALLOW_RESTORE_IN_LOCAL = "AllowRestoreInLocalNode"
    RESTORE_PRE = "RestorePrerequisite"
    RESTORE = "Restore"
    RESTORE_POST = "RestorePostJob"
    RESTORE_GEN_SUB = "restore_gen_sub"
    RESTORE_PER_PROGRESS = f"{RESTORE_PRE}Progress"
    RESTORE_PROGRESS = f"{RESTORE}Progress"
    RESTORE_POST_PROGRESS = f"{RESTORE_POST}Progress"
    # 副本校验
    CHECK_COPY = "check_copy"
    FINALIZE_CLEAR = 'FinalizeClear'


class Db2JsonConstant:
    JOB = "job"
    TYPE = "type"
    SUBTYPE = "subType"
    REPOSITORIES = "repositories"
    REPOSITORY_TYPE = "repositoryType"
    PATH = "path"
    ID = "id"
    PROTECT_OBJECT = "protectObject"
    TARGET_OBJECT = "targetObject"
    TARGET_ENV = "targetEnv"
    NAME = "name"
    JOB_PARAM = "jobParam"
    BACKUP_TYPE = "backupType"
    SUB_JOB = "subJob"
    JOB_NAME = "jobName"
    JOB_ID = "jobId"
    SUB_JOB_ID = "subJobId"
    NODES = "nodes"
    ENDPOINT = "endpoint"
    LOCAL_DB_DIR = "localDatabaseDirectory"
    DB2_USER = "application_auth_authKey"
    DB2_USERS = "applications_0_auth_authKey"
    DB2_PWD = "application_auth_authPwd"
    SANCLIENT_TYPE = "sanclientInvolved"
    # 分片号，用“,”分割
    PTN_NUM = "partitionNumber"
    # 用户名：allow
    JOB_PROTECTENV_NODES_0_AUTH_AUTHKEY = "job_protectEnv_nodes_0_auth_authKey"
    # 用户名：查询权限
    APPENV_NODES_0_AUTH_AUTHKEY = "appEnv_nodes_0_auth_authKey"
    # 恢复目标用户名
    JOB_TARGETENV_NODES_0_AUTH_AUTHKEY = "job_targetEnv_nodes_0_auth_authKey"
    # 恢复
    JOB_COPIES_0_PROTECTENV_NODES_0_AUTH_AUTHKEY = "job_copies_0_protectEnv_nodes_0_auth_authKey"
    JOB_TARGETENV_NODE_AUTH_AUTHKEY = 'job_targetEnv_nodes_{}_auth_authKey_{}'
    RESTORE_COPY_ID = "restoreCopyId"
    RESTORE_TIMESTAMP = "restoreTimestamp"
    # 备份表名
    BACKUP_TABLE = "table_backup"
    # 表创建时间
    TABLE_CREATE_AT = "table_create_at"
    #归档日志开始时间
    ARCHIVE_START_TIME = "start_time"
    # 副本beginTime
    COPY_BEGIN_TIME = "beginTime"
    # 副本endTime
    COPY_END_TIME = "endTime"
    # 副本backupTime
    COPY_BAK_TIME = "backupTime"
    # 是否支持副本校验
    COPY_VERIFY_FILE = "copyVerifyFile"
    # 备份镜像时间The Timestamp for this backup image，样例：20230101100101
    BAK_IMG_TIMESTAMP = "backupImageTimestamp"
    # 数据备份结束时间，样例：20230101100101
    DB2_DATA_BAK_END_TIME = "dataBackupEndTime"
    # 日志副本关联的数据副本ID列表
    ASSOCIATED_COPIES = "associatedCopies"
    # 副本日志扩展信息key
    COPY_LOG_EXT_KEY = "copyLogExtendInfo"
    # 副本当前日志链key
    LOG_CHAIN_KEY = "logChain"
    # 副本分片和日志映射关系key
    PTN_NUM_LOG_MAP_KEY = "ptnNumAndCurLogMap"
    # 日志备份依赖副本类型key
    LOG_BAK_DEPEND_COPY_TYPE = "logBakDependCopyType"
    # 指定时间点恢复失败后的策略
    FAIL_ON_PIT = "failOnPit"
    # 扩展信息
    EXTEND_INFO = "extendInfo"
    PARENT_NAME = "parentName"
    DELETE_LOG = "delete_log"
    COPY_ID = "copyid"
    TRACK_MOD = "trackMod"


class Db2CommonConst:
    # 备份类型和备份目录前缀映射关系
    BACKUP_TYPE_DIR_PREFIX_MAP = {
        BackupTypeEnum.FULL_BACKUP.value: "full",
        BackupTypeEnum.INCRE_BACKUP.value: "incr",
        BackupTypeEnum.DIFF_BACKUP.value: "diff",
    }
    # 备份相关查询进度所有任务名称
    BACKUP_PROGRESS_ACTIONS = (
        Db2JobName.BACKUP_PER_PROGRESS, Db2JobName.BACKUP_PROGRESS, Db2JobName.BACKUP_POST_PROGRESS,
        Db2JobName.ABORT_JOB_PROGRESS
    )
    PARAM_NODE_IP = "node_ip"
    PARAM_JOB_ID = "job_id"
    PARAM_SUB_JOB_ID = "sub_job_id"
    # 方法名和(事件标签,参数名列表)映射关系
    FUNC_NAME_LABEL_PARAMS_MAP = {
        "allow_backup_in_local_node": (None, list()),
        "check_backup_job_type": (None, list()),
        "query_job_permission": (None, list()),
        "exec_backup_pre_job": (None, list()),
        "exec_backup": (ReportDBLabel.BACKUP_SUB_FAILED, [PARAM_SUB_JOB_ID]),
        "exec_backup_post_job": (ReportDBLabel.POST_TASK_FAIL, [PARAM_NODE_IP, PARAM_SUB_JOB_ID]),
        "abort_job": (None, 0),
        "allow_restore_in_local_node": (None, list()),
        "exec_restore_pre_job": (None, list()),
        "exec_restore": (ReportDBLabel.RESTORE_SUB_FAILED, [PARAM_SUB_JOB_ID]),
        "exec_restore_post_job": (ReportDBLabel.POST_TASK_FAIL, [PARAM_NODE_IP, PARAM_SUB_JOB_ID])
    }
    # 恢复相关查询进度所有任务名称
    RESTORE_PROGRESS_ACTIONS = (
        Db2JobName.RESTORE_PER_PROGRESS,
        Db2JobName.RESTORE_PROGRESS,
        Db2JobName.RESTORE_POST_PROGRESS
    )
    # 以最小事务提交时间进行时间点恢复成功
    PIT_RESTORE_SUCCESS_WITH_MIN_TIME = "plugin_pit_restore_success_with_min_time_label"
    # 以日志末尾进行时间点恢复成功
    PIT_RESTORE_SUCCESS_WITH_END_OF_LOGS = "plugin_pit_restore_success_with_logs_label"


class RpcToolApiName:
    """
    rpctool工具接口名
    """
    # 上报副本信息
    REPORT_COPY_ADDITIONAL_INFO = "ReportCopyAdditionalInfo"
    # 查询最新副本
    QUERY_PREVIOUS_COPY = "QueryPreviousCopy"
    # 上报进度
    REPORT_JOB_DETAILS = "ReportJobDetails"


class Db2ConfigSection:
    SECTION_PEXPECT = "PEXPECT"


class Db2ConfigFileName:
    file_name = "configuration/pexpect_config.ini"


class Db2CmdFormat:
    DB_RESTORE = 'su - {} -c "db2 restore db {} {} from {} taken at {} into {} {}' \
                 'without prompting"'
    DB_RESTORE_NEW = 'su - {} -c "db2 restore db {} {} from {} taken at {}{} into {} ' \
                     '{}without prompting"'
    DB_ROLL = 'su - {} -c "db2 rollforward db {} to end of backup and complete overflow log path \({}\) NORETRIEVE"'
    TS_RESTORE = 'su - {} -c "db2 restore db {} tablespace \({}\) {} from {} taken at {} ' \
                 '{}without prompting"'
    TS_ROLL = 'su - {} -c "db2 rollforward db {} to end of backup and ' \
              'complete tablespace \({}\) online overflow log path \({}\)"'
    TS_OFFLINE_BACKUP = 'su - {} -c "db2 backup db {} on all nodes tablespace \({}\) to /dev/null"'
